/**
 * @file serial.c
 * @brief 串口通信驱动实现
 * @author 废话文学创始人
 * @version 1.0
 * @date 2024-02-25
 */

#include "serial.h"
#include "string.h"

uint8_t TXBuffer[TXBUFFERSIZE] = {0}; /**< 发送缓存区 */
uint8_t RXBuffer[RXBUFFERSIZE] = {0}; /**< 接收缓存区 */

/**
 * @brief 阻塞发送格式化字符串
 * @param huart 串口句柄
 * @param format 格式化字符串
 * @param ... 可变参数
 */
void Uart_FormatSend_block(UART_HandleTypeDef *huart, const char *format, ...)
{
    va_list args;                             // 定义一个va_list类型的变量，用来储存单个参数
    va_start(args, format);                   // 使args指向可变参数的第一个参数
    vsprintf((char *)TXBuffer, format, args); // 必须用vprintf等带V的
    va_end(args);                             // 结束可变参数的获取
    HAL_UART_Transmit(huart, TXBuffer, strlen((char *)TXBuffer), TIMEOUT);
}

/**
 * @brief 非阻塞发送格式化字符串
 * @param huart 串口句柄
 * @param format 格式化字符串
 * @param ... 可变参数
 */
void Uart_FormatSend_unblock(UART_HandleTypeDef *huart, const char *format, ...)
{
    va_list args;                             // 定义一个va_list类型的变量，用来储存单个参数
    va_start(args, format);                   // 使args指向可变参数的第一个参数
    vsprintf((char *)TXBuffer, format, args); // 必须用vprintf等带V的
    va_end(args);                             // 结束可变参数的获取
    if (huart->hdmatx != NULL)
    {
        HAL_UART_Transmit_DMA(huart, TXBuffer, strlen((char *)TXBuffer));
    }
    else
    {
        HAL_UART_Transmit_IT(huart, TXBuffer, strlen((char *)TXBuffer));
    }
}

/**
 * @brief 阻塞方式接收不定长数据到缓冲区
 * @param huart 串口句柄
 * @param RxLen_finally 最终接收到的实际数量指针
 */
void Uart_ReceiveToBuffer_block(UART_HandleTypeDef *huart, uint16_t *RxLen_finally)
{
    HAL_UARTEx_ReceiveToIdle(huart, RXBuffer, RXBUFFERSIZE, RxLen_finally, TIMEOUT);
}

/**
 * @brief 非阻塞方式接收不定长数据到缓冲区
 * @param huart 串口句柄
 */
void Uart_ReceiveToBuffer_unblock(UART_HandleTypeDef *huart)
{
    if (huart->hdmarx != NULL)
    {
        HAL_UARTEx_ReceiveToIdle_DMA(huart, RXBuffer, RXBUFFERSIZE);
        __HAL_DMA_DISABLE_IT(huart->hdmarx, DMA_IT_HT);
    }
    else
    {
        HAL_UARTEx_ReceiveToIdle_IT(huart, RXBuffer, RXBUFFERSIZE);
    }
}

/**
 * @brief 串口接收完成事件回调函数
 * @param huart 串口句柄
 * @param Size 实际接收数据长度
 * @note 用户可在此函数中编写数据处理逻辑
 */
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
}
